#ifndef ENTITY_H_INCLUDED
#define ENTITY_H_INCLUDED

namespace Oribi
{
    class Game;
    class Controller;

    #define ENTITY_GENDER_MALE   0
    #define ENTITY_GENDER_FEMALE 1

    #define ENTITY_STATE_IDLE 0
    #define ENTITY_STATE_WALK 1
    #define ENTITY_STATE_RUN  2

    #define DIRECTION_RIGHT      0
    #define DIRECTION_RIGHT_UP   1
    #define DIRECTION_UP         2
    #define DIRECTION_LEFT_UP    3
    #define DIRECTION_LEFT       4
    #define DIRECTION_LEFT_DOWN  5
    #define DIRECTION_DOWN       6
    #define DIRECTION_RIGHT_DOWN 7

    class Entity
    {
    public:
        Entity();
        Entity(const Entity&);
        virtual ~Entity(){}

        virtual Entity *clone() const = 0;
        SDL_Point getPosition() const;
        void setPosition(SDL_Point);

        virtual void blit(GraphicContext&);
        virtual void blit(BlitQueue&);
        virtual void initSprite(Resources&, ConfContext&);

        AnimatedSprite &getSprite();

        void setGender(int g);
        int getGender() const;
        int randomizeGender();

        virtual void updateAnimationToState();
        virtual void setState(int s);
        void setDirection(int d);

        virtual void updateActions();
        virtual void update();

        virtual std::string getEntityTypeName() const = 0;

        friend class Controller;
        friend class EntityAction;
    protected:
        virtual int animOfState();
        virtual bool isValidState(int s) const;

        virtual int getSpriteSheetID() const = 0;

        int state;
        int direction;
        int gender;
        EntityAction *actions;
        SDL_Point position;
        int height;

        void updateHeight(const Map&);
        void setSpritePosition();

        AnimatedSprite sprite;
    };
}

#endif // ENTITY_H_INCLUDED
